#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include "esp_gatt_common_api.h"
#include "esp_bt_defs.h"
#include "ble_core.h"
#include "esp_err.h"
// 打印可用内存信息
#include "esp_heap_caps.h" // 若已包含可省略

// -------------------------- 宏定义 --------------------------
#define BLE_CORE_TAG "BLE_CORE"
#define GATTS_SERVICE_UUID_TEST_A 0x00FF // 服务A UUID
#define GATTS_CHAR_UUID_TEST_A 0xFF01    // 特征A UUID（可通知+读写）
#define GATTS_NUM_HANDLE_TEST_A 4        // 服务A占用句柄数
#define GATTS_SERVICE_UUID_TEST_B 0x00EE // 服务B UUID（备用）
#define GATTS_CHAR_UUID_TEST_B 0xEE01    // 特征B UUID
#define GATTS_NUM_HANDLE_TEST_B 4        // 服务B占用句柄数

#define GATTS_DEMO_CHAR_VAL_LEN_MAX 512 // 特征最大长度
#define ADV_CONFIG_FLAG (1 << 0)        // 广告配置标志
#define SCAN_RSP_CONFIG_FLAG (1 << 1)   // 扫描响应配置标志
#define PREPARE_BUF_MAX_SIZE 1024       // 准备写入缓冲区大小
#define PROFILE_NUM 2                   // 两个Profile（A和B）
#define PROFILE_A_APP_ID 0              // Profile A ID
#define PROFILE_B_APP_ID 1              // Profile B ID

// 准备写入缓冲区（支持长数据写入）
typedef struct
{
    uint8_t *prepare_buf;
    int prepare_len;
} prepare_type_env_t;
static prepare_type_env_t a_prepare_write_env;

const char *_device_name = "ESP32C2-Board"; // 设备名称
// -------------------------- 函数声明 --------------------------
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
static void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param);
static void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param);
// ------------------------- 配网 数据解析 保存函数 -------------------------
static esp_err_t ble_prov_parse_data(uint8_t *data, uint16_t len, char *ssid, char *password);
static esp_err_t ble_prov_save_to_nvs(const char *ssid, const char *password);
// -------------------------- 全局变量 --------------------------
static ble_core_evt_handler_t m_evt_handler = NULL; // 用户事件回调
static uint8_t char1_str[] = {0x11, 0x22, 0x33};    // 特征A默认值
static uint16_t descr_value = 0x0;                  // CCCD值（通知使能状态）
static uint16_t local_mtu = 23;                     // 本地MTU
static uint8_t adv_config_done = 0;                 // 广告配置完成标志

static esp_attr_value_t gatts_demo_char1_val = {
    // 特征A属性值
    .attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX,
    .attr_len = sizeof(char1_str),
    .attr_value = char1_str,
};

static uint8_t adv_service_uuid128[32] = {
    /* LSB <--------------------------------------------------------------------------------> MSB */
    // first uuid, 16bit, [12],[13] is the value
    0xfb,
    0x34,
    0x9b,
    0x5f,
    0x80,
    0x00,
    0x00,
    0x80,
    0x00,
    0x10,
    0x00,
    0x00,
    0xEE,
    0x00,
    0x00,
    0x00,
    // second uuid, 32bit, [12], [13], [14], [15] is the value
    0xfb,
    0x34,
    0x9b,
    0x5f,
    0x80,
    0x00,
    0x00,
    0x80,
    0x00,
    0x10,
    0x00,
    0x00,
    0xFF,
    0x00,
    0x00,
    0x00,
};

// 初始化Profile表
struct gatts_profile_inst gl_profile_tab[PROFILE_NUM] = {
    [PROFILE_A_APP_ID] = {
        .gatts_cb = gatts_profile_a_event_handler,
        .gatts_if = ESP_GATT_IF_NONE,
    },
    [PROFILE_B_APP_ID] = {
        .gatts_cb = gatts_profile_b_event_handler,
        .gatts_if = ESP_GATT_IF_NONE,
    },
};

// 配置主广告数据
esp_ble_adv_data_t adv_data = {
    .set_scan_rsp = false,
    .include_name = true,
    .include_txpower = true,
    .min_interval = 0x0006,
    .max_interval = 0x0010,
    .appearance = 0x00,
    .manufacturer_len = 0,
    .p_manufacturer_data = NULL,
    .service_data_len = 0,
    .p_service_data = NULL,
    .service_uuid_len = sizeof(adv_service_uuid128),
    .p_service_uuid = adv_service_uuid128,
    .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
};
// 配置扫描响应数据
esp_ble_adv_data_t scan_rsp_data = {
    .set_scan_rsp = true,
    .include_name = false,
    .include_txpower = true,
    .appearance = 0x00,
    .manufacturer_len = 0,
    .p_manufacturer_data = NULL,
    .service_data_len = 0,
    .p_service_data = NULL,
    .service_uuid_len = sizeof(adv_service_uuid128),
    .p_service_uuid = adv_service_uuid128,
    .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
};
// 全局广告参数
static esp_ble_adv_params_t adv_params = {
    .adv_int_min = 0x20,
    .adv_int_max = 0x40,
    .adv_type = ADV_TYPE_IND,
    .own_addr_type = BLE_ADDR_TYPE_PUBLIC,
    //.peer_addr            =
    //.peer_addr_type       =
    .channel_map = ADV_CHNL_ALL,
    .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};

// -------------------------- BLE核心初始化 --------------------------
esp_err_t ble_core_init(ble_core_evt_handler_t evt_handler)
{
    esp_err_t ret;
    m_evt_handler = evt_handler;

    // 初始化NVS
    ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    // 释放经典蓝牙内存（仅用BLE）
    ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));

    // 初始化蓝牙控制器
    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    ret = esp_bt_controller_init(&bt_cfg);
    if (ret)
    {
        ESP_LOGE(BLE_CORE_TAG, "Controller init failed");
        return ret;
    }
    ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
    if (ret)
    {
        ESP_LOGE(BLE_CORE_TAG, "Controller enable failed");
        return ret;
    }

    // 初始化Bluedroid协议栈
    ret = esp_bluedroid_init();
    if (ret)
    {
        ESP_LOGE(BLE_CORE_TAG, "Bluedroid init failed");
        return ret;
    }
    ret = esp_bluedroid_enable();
    if (ret)
    {
        ESP_LOGE(BLE_CORE_TAG, "Bluedroid enable failed");
        return ret;
    }

    // 注册GATT/GAP回调
    ret = esp_ble_gatts_register_callback(gatts_event_handler);
    if (ret)
    {
        ESP_LOGE(BLE_CORE_TAG, "GATTS register failed: 0x%x", ret);
        return ret;
    }
    ret = esp_ble_gap_register_callback(gap_event_handler);
    if (ret)
    {
        ESP_LOGE(BLE_CORE_TAG, "GAP register failed: 0x%x", ret);
        return ret;
    }
    // 注册GATT应用（创建服务的前提）
    ret = esp_ble_gatts_app_register(PROFILE_A_APP_ID);
    if (ret)
    {
        ESP_LOGE(BLE_CORE_TAG, "Profile A register failed: 0x%x", ret);
        return ret;
    }
    ret = esp_ble_gatts_app_register(PROFILE_B_APP_ID);
    if (ret)
    {
        ESP_LOGE(BLE_CORE_TAG, "Profile B register failed: 0x%x", ret);
        return ret;
    }

    // 设置MTU
    ret = esp_ble_gatt_set_local_mtu(GATTS_DEMO_CHAR_VAL_LEN_MAX); // 支持更大MTU（默认23）
    if (ret)
    {
        ESP_LOGE(BLE_CORE_TAG, "Set MTU failed: 0x%x", ret);
    }
    else
    {
        local_mtu = GATTS_DEMO_CHAR_VAL_LEN_MAX; // 更新MTU值
    }

    return ESP_OK;
}

void clear_wifi_nvs_info()
{
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);
    ESP_LOGI(BLE_CORE_TAG, "NVS initialized");

    // 读取已保存的WiFi配置
    nvs_handle_t nvs_handle;
    ret = nvs_open(STORED_PROV_NAMESPACE, NVS_READWRITE, &nvs_handle); // 使用之前配网时的命名空间"wifi_prov"
    if (ret == ESP_OK)
    {
        // 读取SSID
        // 方法A：删除指定键（精确删除）
        ret = nvs_erase_key(nvs_handle, STORED_PROV_SSID_KEY); // 删除SSID
        if (ret != ESP_OK)
        {
            ESP_LOGE("NVS_CLEAR", "删除SSID失败: %s", esp_err_to_name(ret));
        }
        ret = nvs_erase_key(nvs_handle, STORED_PROV_PASS_KEY); // 删除密码
        if (ret != ESP_OK)
        {
            ESP_LOGE("NVS_CLEAR", "删除密码失败: %s", esp_err_to_name(ret));
        }
        // 提交更改（必须执行，否则删除不生效）
        ret = nvs_commit(nvs_handle);
        if (ret != ESP_OK)
        {
            ESP_LOGE("NVS_CLEAR", "提交更改失败: %s", esp_err_to_name(ret));
        }
        else
        {
            ESP_LOGI("NVS_CLEAR", "已清除自定义WiFi信息");
        }
        nvs_close(nvs_handle);
    }
    else
    {
        ESP_LOGI("NVS_CLEAR", "无自定义WiFi信息可清除");
    }
}

// 从nvs中获取保存的配网参数
void get_nvs_prov_params(ble_core_evt_handler_t evt_handler)
{
    m_evt_handler = evt_handler;
    // --------------------------------- 检查NVS中是否已有WiFi配置，若有则停止配网流程 --------------------
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);
    ESP_LOGI(BLE_CORE_TAG, "NVS initialized");

    // 3. 从NVS读取已存储的WiFi配置
    char ssid[MAX_SSID_LEN] = {0};
    char password[MAX_PASS_LEN] = {0};
    bool has_saved_config = false;
    // 读取已保存的WiFi配置
    nvs_handle_t nvs_handle;
    ret = nvs_open(STORED_PROV_NAMESPACE, NVS_READONLY, &nvs_handle); // 使用之前配网时的命名空间"wifi_prov"
    if (ret == ESP_OK)
    {
        // 读取SSID
        size_t ssid_len = MAX_SSID_LEN;
        ret = nvs_get_str(nvs_handle, STORED_PROV_SSID_KEY, ssid, &ssid_len);
        if (ret == ESP_OK && strlen(ssid) > 0)
        {
            // 读取密码
            size_t pass_len = MAX_PASS_LEN;
            ret = nvs_get_str(nvs_handle, STORED_PROV_PASS_KEY, password, &pass_len);
            if (ret == ESP_OK)
            {
                has_saved_config = true;
                ESP_LOGI(BLE_CORE_TAG, "Loaded saved WiFi: SSID=%s", ssid);
            }
        }
        nvs_close(nvs_handle);
    }

    // 4. 若有已存储的配置，直接连接WiFi；否则启动BLE配网
    if (has_saved_config)
    {
        // 通知上层应用（触发WiFi连接）
        if (m_evt_handler)
        {
            ble_core_evt_t evt = {
                .type = BLE_CORE_EVT_PROV_SAVED,
                .params.prov = {{0}}};
            strncpy(evt.params.prov.ssid, ssid, MAX_SSID_LEN);
            strncpy(evt.params.prov.password, password, MAX_PASS_LEN);
            m_evt_handler(&evt);
        }
        ble_core_advertise_stop();
    }
    else
    {
        ESP_LOGI(BLE_CORE_TAG, "No saved WiFi config, starting BLE provisioning");
        // 启动BLE配网（使用之前的BLE初始化逻辑）
        ble_core_init(m_evt_handler);
        ble_core_advertise_start("ESP32C2-Board");
    }
}

// -------------------------- GAP事件处理（广告/连接参数） --------------------------
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
    switch (event)
    {
    case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
        adv_config_done &= (~ADV_CONFIG_FLAG);
        if (adv_config_done == 0)
        {
            esp_ble_gap_start_advertising(&adv_params); // 仅当广告数据和扫描响应都配置完成后启动
        }
        break;
    case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
        adv_config_done &= (~SCAN_RSP_CONFIG_FLAG);
        if (adv_config_done == 0)
        {
            esp_ble_gap_start_advertising(&adv_params); // 同上
        }
        break;
    case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
        if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS)
        {
            ESP_LOGE(BLE_CORE_TAG, "Advertising start failed");
        }
        else
        {
            ESP_LOGI(BLE_CORE_TAG, "Advertising started");
        }
        break;
    case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
        if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS)
        {
            ESP_LOGE(BLE_CORE_TAG, "Advertising stop failed");
        }
        else
        {
            ESP_LOGI(BLE_CORE_TAG, "Advertising stopped");
        }
        break;
    case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
        ESP_LOGI(BLE_CORE_TAG, "Conn params updated: int=%d, latency=%d",
                 param->update_conn_params.conn_int, param->update_conn_params.latency);
        break;
    default:
        break;
    }
}

// -------------------------- GATTS全局事件分发 --------------------------
static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
{
    /* If event is register event, store the gatts_if for each profile */
    if (event == ESP_GATTS_REG_EVT)
    {
        if (param->reg.status == ESP_GATT_OK)
        {
            gl_profile_tab[param->reg.app_id].gatts_if = gatts_if;
        }
        else
        {
            ESP_LOGI(BLE_CORE_TAG, "Reg app failed, app_id %04x, status %d",
                     param->reg.app_id,
                     param->reg.status);
            return;
        }
    }

    /* If the gatts_if equal to profile A, call profile A cb handler,
     * so here call each profile's callback */
    do
    {
        int idx;
        for (idx = 0; idx < PROFILE_NUM; idx++)
        {
            if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
                gatts_if == gl_profile_tab[idx].gatts_if)
            {
                if (gl_profile_tab[idx].gatts_cb)
                {
                    gl_profile_tab[idx].gatts_cb(event, gatts_if, param);
                }
            }
        }
    } while (0);
}

// -------------------------- 停止广告 --------------------------
esp_err_t ble_core_advertise_stop()
{
    return esp_ble_gap_stop_advertising();
}

// -------------------------- 发送通知 --------------------------
esp_err_t ble_core_notify(uint16_t conn_id, uint16_t handle, uint8_t *data, uint16_t len)
{
    if (!data || len == 0 || conn_id == -1 || handle == -1)
    {
        return ESP_ERR_INVALID_ARG;
    }
    return esp_ble_gatts_send_indicate(
        gl_profile_tab[PROFILE_A_APP_ID].gatts_if,
        conn_id,
        handle,
        len,
        data,
        false // 通知（无需应答）
    );
}

// -------------------------- Profile A事件处理 --------------------------
static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
{
    switch (event)
    {
    // 1. 应用注册完成：创建服务
    case ESP_GATTS_REG_EVT:
    {
        ESP_LOGI(BLE_CORE_TAG, "GATT server register, status %d, app_id %d, gatts_if %d", param->reg.status, param->reg.app_id, gatts_if);
        gl_profile_tab[PROFILE_A_APP_ID].service_id.is_primary = true;
        gl_profile_tab[PROFILE_A_APP_ID].service_id.id.inst_id = 0x00;
        gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16;
        gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_A;

        esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_A);
        break;
    }

    // 2. 服务创建完成：添加特征
    case ESP_GATTS_CREATE_EVT:
    {
        // 仅记录服务句柄（服务创建时无特征句柄）
        gl_profile_tab[PROFILE_A_APP_ID].service_handle = param->create.service_handle;
        ESP_LOGI(BLE_CORE_TAG, "Service A created, handle=0x%x", param->create.service_handle);

        // 配置特征属性并添加特征
        esp_gatt_char_prop_t property = ESP_GATT_CHAR_PROP_BIT_READ |
                                        ESP_GATT_CHAR_PROP_BIT_WRITE |
                                        ESP_GATT_CHAR_PROP_BIT_NOTIFY;
        esp_bt_uuid_t char_uuid = {.len = ESP_UUID_LEN_16, .uuid = {.uuid16 = GATTS_CHAR_UUID_TEST_A}};
        esp_gatt_perm_t perm = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE;

        esp_ble_gatts_add_char(
            gl_profile_tab[PROFILE_A_APP_ID].service_handle,
            &char_uuid,
            perm,
            property,
            &gatts_demo_char1_val,
            NULL);
        break;
    }

    // 3. 特征添加完成：获取特征句柄+添加CCCD
    case ESP_GATTS_ADD_CHAR_EVT:
    {
        // 记录特征句柄（特征添加后才有此句柄）
        gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle;
        ESP_LOGI(BLE_CORE_TAG, "Char A added, handle=0x%x", param->add_char.attr_handle);

        // 添加CCCD描述符（用于控制通知）
        esp_bt_uuid_t cccd_uuid = {.len = ESP_UUID_LEN_16, .uuid = {.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG}};
        esp_ble_gatts_add_char_descr(
            gl_profile_tab[PROFILE_A_APP_ID].service_handle,
            &cccd_uuid,
            ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
            NULL,
            NULL);
        break;
    }

    // 4. CCCD描述符添加完成：启动服务
    case ESP_GATTS_ADD_CHAR_DESCR_EVT:
    {
        gl_profile_tab[PROFILE_A_APP_ID].descr_handle = param->add_char_descr.attr_handle;
        ESP_LOGI(BLE_CORE_TAG, "CCCD added, handle=0x%x", param->add_char_descr.attr_handle);
        esp_ble_gatts_start_service(gl_profile_tab[PROFILE_A_APP_ID].service_handle);
        break;
    }

    // 5. 设备连接
    case ESP_GATTS_CONNECT_EVT:
    {
        gl_profile_tab[PROFILE_A_APP_ID].conn_id = param->connect.conn_id;
        // 保存远程设备蓝牙地址
        memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, param->connect.remote_bda, ESP_BD_ADDR_LEN);

        if (m_evt_handler)
        {
            ble_core_evt_t evt = {
                .type = BLE_CORE_EVT_CONNECT,
                .params.conn = {
                    .conn_id = param->connect.conn_id,
                }};
            memcpy(evt.params.conn.bda, param->connect.remote_bda, ESP_BD_ADDR_LEN);
            m_evt_handler(&evt);
        }
        break;
    }

    // 6. 设备断开
    case ESP_GATTS_DISCONNECT_EVT:
    {
        if (m_evt_handler)
        {
            ble_core_evt_t evt = {
                .type = BLE_CORE_EVT_DISCONNECT,
                .params.conn = {
                    .conn_id = param->disconnect.conn_id,
                }};
            m_evt_handler(&evt);
        }
        ble_core_advertise_start("ESP32C2_BLE"); // 重新广播
        break;
    }

    // 7. 写入事件（含CCCD控制）
    case ESP_GATTS_WRITE_EVT:
    {
        ESP_LOGI(BLE_CORE_TAG, "Characteristic write, conn_id %d, trans_id %" PRIu32 ", handle %d", param->write.conn_id, param->write.trans_id, param->write.handle);
        // 处理CCCD写入（通知使能/禁用）
        if (param->write.handle == gl_profile_tab[PROFILE_A_APP_ID].descr_handle)
        {
            descr_value = (param->write.value[1] << 8) | param->write.value[0]; // 16位小端值
            if (descr_value == 0x0001)
            { // 通知使能
                if (m_evt_handler)
                {
                    ble_core_evt_t evt = {.type = BLE_CORE_EVT_NOTIFY_ENABLE};
                    m_evt_handler(&evt);
                }
            }
            else
            { // 通知禁用
                if (m_evt_handler)
                {
                    ble_core_evt_t evt = {.type = BLE_CORE_EVT_NOTIFY_DISABLE};
                    m_evt_handler(&evt);
                }
            }
            esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL);
            break;
        }

        // 处理特征写入（普通写入/准备写入）
        if (param->write.is_prep)
        { // 准备写入（长数据）
            example_write_event_env(gatts_if, &a_prepare_write_env, param);
        }
        else
        { // 普通写入
            // 更新本地特征值
            if (param->write.len <= GATTS_DEMO_CHAR_VAL_LEN_MAX)
            {
                memcpy(gatts_demo_char1_val.attr_value, param->write.value, param->write.len);
                gatts_demo_char1_val.attr_len = param->write.len;
            }

            // -------------------------- 新增配网逻辑 --------------------------
            // 仅处理配网特征的数据
            if (param->write.handle == gl_profile_tab[PROFILE_A_APP_ID].char_handle &&
                s_prov_state == BLE_PROV_STATE_IDLE)
            {

                char ssid[MAX_SSID_LEN] = {0};
                char password[MAX_PASS_LEN] = {0};
                esp_err_t err = ble_prov_parse_data(param->write.value, param->write.len, ssid, password);
                if (err == ESP_OK)
                {
                    // 解析成功，保存到NVS
                    err = ble_prov_save_to_nvs(ssid, password);
                    if (err == ESP_OK)
                    {
                        s_prov_state = BLE_PROV_STATE_SAVED;
                        // 配网成功，停止广播
                        ble_core_advertise_stop();
                        // ble_core_deinit();
                        // 配网成功后简化的销毁流程（替代完整的ble_core_deinit）
                        esp_ble_gap_stop_advertising();
                        vTaskDelay(pdMS_TO_TICKS(1000));
                        esp_bluedroid_disable();
                        esp_bluedroid_deinit();
                        esp_bt_controller_disable();
                        esp_bt_controller_deinit();

                        // 7. 释放动态内存
                        if (a_prepare_write_env.prepare_buf != NULL)
                        {
                            free(a_prepare_write_env.prepare_buf);
                            a_prepare_write_env.prepare_buf = NULL;
                            a_prepare_write_env.prepare_len = 0;
                            ESP_LOGI(BLE_CORE_TAG, "Released prepare write buffer");
                        }

                        // 8. 重置全局变量
                        local_mtu = 23;
                        adv_config_done = 0;

                        ESP_LOGI(BLE_CORE_TAG, "BLE deinitialized after provisioning");

                        size_t free_heap = heap_caps_get_free_size(MALLOC_CAP_DEFAULT);
                        size_t total_heap = heap_caps_get_total_size(MALLOC_CAP_DEFAULT);
                        size_t min_free_heap = heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT);

                        ESP_LOGI(BLE_CORE_TAG, "内存信息 - 可用: %d KB, 总容量: %d KB, 历史最小可用: %d KB",
                                 free_heap / 1024,
                                 total_heap / 1024,
                                 min_free_heap / 1024);

                        // 通知上层应用（触发WiFi连接）
                        if (m_evt_handler)
                        {
                            ble_core_evt_t evt = {
                                .type = BLE_CORE_EVT_PROV_SAVED,
                                .params.prov = {{0}}};
                            strncpy(evt.params.prov.ssid, ssid, MAX_SSID_LEN);
                            strncpy(evt.params.prov.password, password, MAX_PASS_LEN);
                            m_evt_handler(&evt);
                        }

                        m_evt_handler = NULL; // 避免重复调用
                        s_prov_state = BLE_PROV_STATE_IDLE;
                    }
                    else
                    {
                        s_prov_state = BLE_PROV_STATE_FAILED;
                        if (m_evt_handler)
                        {
                            ble_core_evt_t evt = {.type = BLE_CORE_EVT_PROV_FAILED};
                            m_evt_handler(&evt);
                        }
                    }
                }
                else
                {
                    s_prov_state = BLE_PROV_STATE_FAILED;
                    if (m_evt_handler)
                    {
                        ble_core_evt_t evt = {.type = BLE_CORE_EVT_PROV_FAILED};
                        m_evt_handler(&evt);
                    }
                }
            }
            // ------------------------------------------------------------------

            // 通知用户
            if (m_evt_handler)
            {
                ble_core_evt_t evt = {
                    .type = BLE_CORE_EVT_WRITE,
                    .params.data = {
                        .handle = param->write.handle,
                        .len = param->write.len,
                        .data = param->write.value}};
                m_evt_handler(&evt);
            }
            esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL);
        }
        break;
    }

    // 8. 执行写入（提交长数据）
    case ESP_GATTS_EXEC_WRITE_EVT:
    {
        example_exec_write_event_env(&a_prepare_write_env, param);
        // 通知用户长数据写入完成
        if (m_evt_handler && a_prepare_write_env.prepare_len > 0)
        {
            ble_core_evt_t evt = {
                .type = BLE_CORE_EVT_WRITE,
                .params.data = {
                    .handle = gl_profile_tab[PROFILE_A_APP_ID].char_handle,
                    .len = a_prepare_write_env.prepare_len,
                    .data = a_prepare_write_env.prepare_buf}};
            m_evt_handler(&evt);
        }
        // -------------------------- 新增配网逻辑（长数据） --------------------------
        if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC && // 执行写入
            a_prepare_write_env.prepare_len > 0 &&                           // 有有效数据
            s_prov_state == BLE_PROV_STATE_IDLE)
        { // 未配网状态

            char ssid[MAX_SSID_LEN] = {0};
            char password[MAX_PASS_LEN] = {0};
            esp_err_t err = ble_prov_parse_data(
                a_prepare_write_env.prepare_buf,
                a_prepare_write_env.prepare_len,
                ssid,
                password);
            if (err == ESP_OK)
            {
                // 解析成功，保存到NVS
                err = ble_prov_save_to_nvs(ssid, password);
                if (err == ESP_OK)
                {
                    s_prov_state = BLE_PROV_STATE_SAVED;
                    // 配网成功，停止广播
                    ble_core_advertise_stop();
                    // ble_core_deinit();
                    // 配网成功后简化的销毁流程（替代完整的ble_core_deinit）
                    esp_ble_gap_stop_advertising();
                    vTaskDelay(pdMS_TO_TICKS(1000));
                    esp_bluedroid_disable();
                    esp_bluedroid_deinit();
                    esp_bt_controller_disable();
                    esp_bt_controller_deinit();

                    // 7. 释放动态内存
                    if (a_prepare_write_env.prepare_buf != NULL)
                    {
                        free(a_prepare_write_env.prepare_buf);
                        a_prepare_write_env.prepare_buf = NULL;
                        a_prepare_write_env.prepare_len = 0;
                        ESP_LOGI(BLE_CORE_TAG, "Released prepare write buffer");
                    }

                    // 8. 重置全局变量
                    local_mtu = 23;
                    adv_config_done = 0;

                    ESP_LOGI(BLE_CORE_TAG, "BLE deinitialization completed");
                    ESP_LOGI(BLE_CORE_TAG, "BLE deinitialized after provisioning");

                    size_t free_heap = heap_caps_get_free_size(MALLOC_CAP_DEFAULT);
                    size_t total_heap = heap_caps_get_total_size(MALLOC_CAP_DEFAULT);
                    size_t min_free_heap = heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT);

                    ESP_LOGI(BLE_CORE_TAG, "内存信息 - 可用: %d KB, 总容量: %d KB, 历史最小可用: %d KB",
                             free_heap / 1024,
                             total_heap / 1024,
                             min_free_heap / 1024);

                    // 通知上层应用（触发WiFi连接）
                    if (m_evt_handler)
                    {
                        ble_core_evt_t evt = {
                            .type = BLE_CORE_EVT_PROV_SAVED,
                            .params.prov = {{0}}};
                        strncpy(evt.params.prov.ssid, ssid, MAX_SSID_LEN);
                        strncpy(evt.params.prov.password, password, MAX_PASS_LEN);
                        m_evt_handler(&evt);
                    }
                    m_evt_handler = NULL; // 避免重复调用
                    s_prov_state = BLE_PROV_STATE_IDLE;
                }
                else
                {
                    s_prov_state = BLE_PROV_STATE_FAILED;
                    if (m_evt_handler)
                    {
                        ble_core_evt_t evt = {.type = BLE_CORE_EVT_PROV_FAILED};
                        m_evt_handler(&evt);
                    }
                }
            }
            else
            {
                s_prov_state = BLE_PROV_STATE_FAILED;
                if (m_evt_handler)
                {
                    ble_core_evt_t evt = {.type = BLE_CORE_EVT_PROV_FAILED};
                    m_evt_handler(&evt);
                }
            }
        }
        // ------------------------------------------------------------------
        break;
    }

    // 9. 读事件
    case ESP_GATTS_READ_EVT:
    {
        ESP_LOGI(BLE_CORE_TAG,
                 "Characteristic read request: conn_id=%d, trans_id=%" PRIu32 ", handle=%d, is_long=%d, offset=%d, need_rsp=%d",
                 param->read.conn_id, param->read.trans_id, param->read.handle,
                 param->read.is_long, param->read.offset, param->read.need_rsp);
        // If no response is needed, exit early (stack handles it automatically)
        if (!param->read.need_rsp)
        {
            return;
        }
        // 响应读请求
        esp_gatt_rsp_t rsp;
        memset(&rsp, 0, sizeof(esp_gatt_rsp_t));
        rsp.attr_value.handle = param->read.handle;
        rsp.attr_value.len = gatts_demo_char1_val.attr_len;
        memcpy(rsp.attr_value.value, gatts_demo_char1_val.attr_value, rsp.attr_value.len);
        esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id, ESP_GATT_OK, &rsp);

        // 通知用户
        if (m_evt_handler)
        {
            ble_core_evt_t evt = {
                .type = BLE_CORE_EVT_READ,
                .params.data = {
                    .handle = param->read.handle,
                    .len = gatts_demo_char1_val.attr_len,
                    .data = gatts_demo_char1_val.attr_value}};
            m_evt_handler(&evt);
        }
        break;
    }

    // 10. MTU更新
    case ESP_GATTS_MTU_EVT:
    {
        local_mtu = param->mtu.mtu;
        ESP_LOGI(BLE_CORE_TAG, "MTU updated to %d", local_mtu);
        break;
    }

    default:
        break;
    }
}
// 关闭蓝牙并释放内存
esp_err_t ble_core_deinit(void)
{
    esp_err_t ret = ESP_OK;
    ESP_LOGI(BLE_CORE_TAG, "Starting BLE deinitialization...");

    // 1. 停止BLE广播
    if (ble_core_advertise_stop() != ESP_OK)
    {
        ESP_LOGW(BLE_CORE_TAG, "Warning: Failed to stop advertising (may not be advertising)");
    }
    ESP_LOGI(BLE_CORE_TAG, "Step 1: Advertising stopped");

    // 2. 断开所有活跃连接
    bool has_connections = false;
    for (int i = 0; i < PROFILE_NUM; i++)
    {
        if (gl_profile_tab[i].conn_id != 0 && gl_profile_tab[i].gatts_if != ESP_GATT_IF_NONE)
        {
            has_connections = true;
            ret = esp_ble_gap_disconnect(gl_profile_tab[i].remote_bda);
            if (ret != ESP_OK)
            {
                ESP_LOGE(BLE_CORE_TAG, "Failed to disconnect profile %d, ret=0x%x", i, ret);
            }
            else
            {
                ESP_LOGI(BLE_CORE_TAG, "Sent disconnect request for profile %d (conn_id=%d)", i, gl_profile_tab[i].conn_id);
                gl_profile_tab[i].conn_id = 0;
            }
        }
    }
    // 若有连接，等待断开完成（延长延迟至1000ms，应对HCI层延迟）
    if (has_connections)
    {
        ESP_LOGI(BLE_CORE_TAG, "Waiting for HCI disconnect complete...");
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
    ESP_LOGI(BLE_CORE_TAG, "Step 2: Connections handled");

    // 3. 停止GATT服务
    for (int i = 0; i < PROFILE_NUM; i++)
    {
        if (gl_profile_tab[i].service_handle != 0 && gl_profile_tab[i].gatts_if != ESP_GATT_IF_NONE)
        {
            ret = esp_ble_gatts_stop_service(gl_profile_tab[i].service_handle);
            if (ret != ESP_OK)
            {
                ESP_LOGE(BLE_CORE_TAG, "Failed to stop service %d, ret=0x%x", i, ret);
            }
            else
            {
                ESP_LOGI(BLE_CORE_TAG, "Stopped service %d (handle=0x%x)", i, gl_profile_tab[i].service_handle);
                gl_profile_tab[i].service_handle = 0;
            }
        }
    }
    ESP_LOGI(BLE_CORE_TAG, "Step 3: Services stopped");

    // 4. 注销GATT应用
    for (int i = 0; i < PROFILE_NUM; i++)
    {
        if (gl_profile_tab[i].gatts_if != ESP_GATT_IF_NONE)
        {
            ret = esp_ble_gatts_app_unregister(gl_profile_tab[i].app_id);
            if (ret != ESP_OK)
            {
                ESP_LOGE(BLE_CORE_TAG, "Failed to unregister profile %d, ret=0x%x", i, ret);
            }
            else
            {
                ESP_LOGI(BLE_CORE_TAG, "Unregistered profile %d", i);
                gl_profile_tab[i].gatts_if = ESP_GATT_IF_NONE;
                gl_profile_tab[i].app_id = 0;
            }
        }
    }
    vTaskDelay(pdMS_TO_TICKS(10000)); // 延长等待，确保应用注销完成
    ESP_LOGI(BLE_CORE_TAG, "Step 4: Profiles unregistered");

    // 5. 禁用并销毁Bluedroid协议栈（调整日志顺序，先打印再执行）
    ESP_LOGI(BLE_CORE_TAG, "Step 5: Disabling Bluedroid...");
    ret = esp_bluedroid_disable();
    if (ret != ESP_OK)
    {
        ESP_LOGE(BLE_CORE_TAG, "Failed to disable Bluedroid, ret=0x%x", ret);
    }
    else
    {
        ESP_LOGI(BLE_CORE_TAG, "Bluedroid disabled successfully");
    }

    ESP_LOGI(BLE_CORE_TAG, "Step 5: Deinitializing Bluedroid...");
    ret = esp_bluedroid_deinit();
    if (ret != ESP_OK)
    {
        ESP_LOGE(BLE_CORE_TAG, "Failed to deinit Bluedroid, ret=0x%x", ret);
    }
    else
    {
        ESP_LOGI(BLE_CORE_TAG, "Bluedroid deinitialized successfully");
    }

    // 6. 关闭并销毁蓝牙控制器
    ESP_LOGI(BLE_CORE_TAG, "Step 6: Checking BT controller status...");
    esp_bt_controller_status_t ctrl_status = esp_bt_controller_get_status();
    ESP_LOGI(BLE_CORE_TAG, "BT controller current status: %d (0=disabled, 1=enabled)", ctrl_status);

    if (ctrl_status == ESP_BT_CONTROLLER_STATUS_ENABLED)
    {
        ESP_LOGI(BLE_CORE_TAG, "Step 6: Disabling BT controller...");
        ret = esp_bt_controller_disable();
        if (ret != ESP_OK)
        {
            ESP_LOGE(BLE_CORE_TAG, "Failed to disable BT controller, ret=0x%x", ret);
        }
        else
        {
            ESP_LOGI(BLE_CORE_TAG, "BT controller disabled successfully");
            ESP_LOGI(BLE_CORE_TAG, "Step 6: Deinitializing BT controller...");
            ret = esp_bt_controller_deinit();
            if (ret != ESP_OK)
            {
                ESP_LOGE(BLE_CORE_TAG, "Failed to deinit BT controller, ret=0x%x", ret);
            }
            else
            {
                ESP_LOGI(BLE_CORE_TAG, "BT controller deinitialized successfully");
            }
        }
    }
    else
    {
        ESP_LOGI(BLE_CORE_TAG, "BT controller is already disabled");
    }

    // 7. 释放动态内存
    if (a_prepare_write_env.prepare_buf != NULL)
    {
        free(a_prepare_write_env.prepare_buf);
        a_prepare_write_env.prepare_buf = NULL;
        a_prepare_write_env.prepare_len = 0;
        ESP_LOGI(BLE_CORE_TAG, "Released prepare write buffer");
    }

    // 8. 重置全局变量
    s_prov_state = BLE_PROV_STATE_IDLE;
    local_mtu = 23;
    adv_config_done = 0;

    ESP_LOGI(BLE_CORE_TAG, "BLE deinitialization completed");
    return ret;
}
// -------------------------- Profile B事件处理 --------------------------
static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
{
    switch (event)
    {
    case ESP_GATTS_REG_EVT:
    {
        esp_gatt_srvc_id_t srvc_id = {
            .id.inst_id = PROFILE_B_APP_ID,
            .id.uuid.len = ESP_UUID_LEN_16,
            .id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_B,
        };
        esp_ble_gatts_create_service(gatts_if, &srvc_id, GATTS_NUM_HANDLE_TEST_B);
        break;
    }

    case ESP_GATTS_CREATE_EVT:
    {
        gl_profile_tab[PROFILE_B_APP_ID].service_handle = param->create.service_handle;
        ESP_LOGI(BLE_CORE_TAG, "Service B created, handle=0x%x", param->create.service_handle);

        // 添加特征B
        esp_gatt_char_prop_t property = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE;
        esp_bt_uuid_t char_uuid = {.len = ESP_UUID_LEN_16, .uuid = {.uuid16 = GATTS_CHAR_UUID_TEST_B}};
        esp_gatt_perm_t perm = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE;

        esp_ble_gatts_add_char(
            gl_profile_tab[PROFILE_B_APP_ID].service_handle,
            &char_uuid,
            perm,
            property,
            &gatts_demo_char1_val,
            NULL);
        break;
    }

    case ESP_GATTS_ADD_CHAR_EVT:
    {
        gl_profile_tab[PROFILE_B_APP_ID].char_handle = param->add_char.attr_handle;
        ESP_LOGI(BLE_CORE_TAG, "Char B added, handle=0x%x", param->add_char.attr_handle);
        esp_ble_gatts_start_service(gl_profile_tab[PROFILE_B_APP_ID].service_handle);
        break;
    }

    default:
        break;
    }
}

// -------------------------- 启动广告 --------------------------
esp_err_t ble_core_advertise_start(const char *device_name)
{
    esp_err_t ret;
    if (!device_name)
        return ESP_ERR_INVALID_ARG;

    // 1. 设置短设备名称（避免长度超限）
    ret = esp_ble_gap_set_device_name(device_name);
    if (ret != ESP_OK)
    {
        ESP_LOGE(BLE_CORE_TAG, "Set device name failed: 0x%x", ret);
        return ret;
    }

    ret = esp_ble_gap_config_adv_data(&adv_data);
    if (ret != ESP_OK)
    {
        ESP_LOGE(BLE_CORE_TAG, "Config adv data failed: 0x%x", ret);
        return ret;
    }

    ret = esp_ble_gap_config_adv_data(&scan_rsp_data);
    if (ret != ESP_OK)
    {
        ESP_LOGE(BLE_CORE_TAG, "Config scan response data failed: 0x%x", ret);
        return ret;
    }
    // 5. 启动广告
    adv_config_done = ADV_CONFIG_FLAG | SCAN_RSP_CONFIG_FLAG;
    return ESP_OK;
}

// -------------------------- 准备写入处理（长数据分片） --------------------------
static void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param)
{
    if (!prepare_write_env->prepare_buf)
    {
        prepare_write_env->prepare_buf = malloc(PREPARE_BUF_MAX_SIZE);
        if (!prepare_write_env->prepare_buf)
        {
            ESP_LOGE(BLE_CORE_TAG, "Malloc prepare buffer failed");
            esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_NO_RESOURCES, NULL);
            return;
        }
        prepare_write_env->prepare_len = 0;
    }

    // 复制分片数据到缓冲区
    int copy_len = param->write.len;
    if (prepare_write_env->prepare_len + copy_len > PREPARE_BUF_MAX_SIZE)
    {
        copy_len = PREPARE_BUF_MAX_SIZE - prepare_write_env->prepare_len;
    }
    memcpy(prepare_write_env->prepare_buf + prepare_write_env->prepare_len, param->write.value, copy_len);
    prepare_write_env->prepare_len += copy_len;

    // 响应准备写入请求
    esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL);
}

// -------------------------- 执行写入处理（提交长数据） --------------------------
static void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param)
{
    if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC)
    { // 执行写入
        if (prepare_write_env->prepare_buf && prepare_write_env->prepare_len > 0)
        {
            // 更新特征值
            memcpy(gatts_demo_char1_val.attr_value, prepare_write_env->prepare_buf, prepare_write_env->prepare_len);
            gatts_demo_char1_val.attr_len = prepare_write_env->prepare_len;
        }
    }
    else
    { // 取消写入
        ESP_LOGI(BLE_CORE_TAG, "Prepare write cancelled");
    }

    // 释放缓冲区
    if (prepare_write_env->prepare_buf)
    {
        free(prepare_write_env->prepare_buf);
        prepare_write_env->prepare_buf = NULL;
    }
    prepare_write_env->prepare_len = 0;
}
// -------------------------- 配网数据解析 --------------------------
static esp_err_t ble_prov_parse_data(uint8_t *data, uint16_t len, char *ssid, char *password)
{
    if (!data || len == 0 || !ssid || !password)
    {
        return ESP_ERR_INVALID_ARG;
    }

    // 转换为字符串（确保以'\0'结尾）
    char prov_str[MAX_SSID_LEN + MAX_PASS_LEN + 2] = {0}; // +2: 分隔符和终止符
    size_t copy_len = (len < sizeof(prov_str) - 1) ? len : sizeof(prov_str) - 1;
    memcpy(prov_str, data, copy_len);

    // 用分隔符拆分SSID和密码
    char *ssid_ptr = strchr(prov_str, PROV_DATA_DELIMITER);
    if (!ssid_ptr)
    {
        ESP_LOGE(BLE_CORE_TAG, "Invalid format (no delimiter '%c')", PROV_DATA_DELIMITER);
        return ESP_ERR_INVALID_ARG;
    }
    *ssid_ptr = '\0'; // 拆分SSID和密码
    char *pass_ptr = ssid_ptr + 1;

    // 校验长度
    if (strlen(prov_str) == 0 || strlen(pass_ptr) == 0)
    {
        ESP_LOGE(BLE_CORE_TAG, "SSID or password is empty");
        return ESP_ERR_INVALID_ARG;
    }
    if (strlen(prov_str) > MAX_SSID_LEN - 1)
    {
        ESP_LOGE(BLE_CORE_TAG, "SSID too long (max %d)", MAX_SSID_LEN - 1);
        return ESP_ERR_INVALID_ARG;
    }
    if (strlen(pass_ptr) > MAX_PASS_LEN - 1)
    {
        ESP_LOGE(BLE_CORE_TAG, "Password too long (max %d)", MAX_PASS_LEN - 1);
        return ESP_ERR_INVALID_ARG;
    }

    // 复制结果
    strncpy(ssid, prov_str, MAX_SSID_LEN - 1);
    strncpy(password, pass_ptr, MAX_PASS_LEN - 1);
    return ESP_OK;
}
// -------------------------- 保存配网数据到NVS --------------------------
static esp_err_t ble_prov_save_to_nvs(const char *ssid, const char *password)
{
    if (!ssid || !password || strlen(ssid) == 0)
    {
        return ESP_ERR_INVALID_ARG;
    }

    nvs_handle_t nvs_handle;
    esp_err_t err = nvs_open("wifi_prov", NVS_READWRITE, &nvs_handle);
    if (err != ESP_OK)
    {
        ESP_LOGE(BLE_CORE_TAG, "NVS open failed: %s", esp_err_to_name(err));
        return err;
    }

    // 保存SSID和密码
    err = nvs_set_str(nvs_handle, "ssid", ssid);
    if (err != ESP_OK)
    {
        ESP_LOGE(BLE_CORE_TAG, "NVS save SSID failed: %s", esp_err_to_name(err));
        nvs_close(nvs_handle);
        return err;
    }

    err = nvs_set_str(nvs_handle, "password", password);
    if (err != ESP_OK)
    {
        ESP_LOGE(BLE_CORE_TAG, "NVS save password failed: %s", esp_err_to_name(err));
        nvs_close(nvs_handle);
        return err;
    }

    // 提交并关闭
    err = nvs_commit(nvs_handle);
    nvs_close(nvs_handle);
    if (err != ESP_OK)
    {
        ESP_LOGE(BLE_CORE_TAG, "NVS commit failed: %s", esp_err_to_name(err));
        return err;
    }

    ESP_LOGI(BLE_CORE_TAG, "WiFi config saved to NVS: SSID=%s", ssid);
    return ESP_OK;
}